﻿using System.Collections.Generic;
using DingTalk.Api;
using DingTalk.Api.Request;
using DingTalk.Api.Response;
using DingTalkAPIHelp.Base;
using static DingTalk.Api.Request.OapiProcessDeleteRequest;
using static DingTalk.Api.Request.OapiProcessSaveRequest;
using static DingTalk.Api.Request.OapiProcessWorkrecordCreateRequest;
using static DingTalk.Api.Request.OapiProcessWorkrecordTaskCreateRequest;
using static DingTalk.Api.Request.OapiProcessWorkrecordTaskgroupCancelRequest;

namespace DingTalkAPIHelp.Flow
{
    public class WorkRecord : SysConfigManager
    {
        private static WorkRecord manager = new WorkRecord();
        /// <summary>
        /// 审批管理实例(单例)
        /// </summary>
        public static WorkRecord Instance
        {
            get
            {
                return manager;
            }
        }

        /// <summary>
        /// 1.获取自有流程模板Code
        /// </summary>
        /// <param name="processName"></param>
        /// <returns></returns>
        public OapiProcessGetByNameResponse GetProcessCodeByName(string processName)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/process/get_by_name");
            OapiProcessGetByNameRequest req = new OapiProcessGetByNameRequest();
            req.Name = processName;
            OapiProcessGetByNameResponse rsp = client.Execute(req, accessToken);
            return rsp;
        }

        /// <summary>
        /// 2.自有工作流 - 删除模板
        /// </summary>
        /// <param name="process_code">模板的唯一码</param>
        /// <param name="clean_running_task">是否清理运行中的任务</param>
        public OapiProcessDeleteResponse ProcessDelete(string process_code, bool clean_running_task)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/process/delete");
            OapiProcessDeleteRequest req = new OapiProcessDeleteRequest();
            DeleteProcessRequestDomain obj1 = new DeleteProcessRequestDomain();
            obj1.Agentid = AgentId;
            obj1.ProcessCode = process_code;
            req.Request_ = obj1;

            OapiProcessDeleteResponse rsp = client.Execute(req, accessToken);
            return rsp;
        }

        /// <summary>
        ///3.自有工作流 - 新增/修改
        /// </summary>
        /// <param name="ProcessCode">审批模板流Code</param>
        /// <param name="ProcessName">审批模板名称</param>
        /// <param name="config">审批模板配置</param>
        /// <param name="formdata">审批表单数据</param>
        /// <returns></returns>
        public OapiProcessSaveResponse ProcessSave(string ProcessCode, string ProcessName, ProcessConfigDomain config, List<FormComponentVoDomain> formdata)
        {
            DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/process/save");
            OapiProcessSaveRequest request = new OapiProcessSaveRequest();
            SaveProcessRequestDomain saveProcessRequest = new SaveProcessRequestDomain();
            if (config == null)
            {
                config = new ProcessConfigDomain();
                config.DisableFormEdit = false;//审批后台管理中是否禁用编辑
                config.DisableHomepage = false;//审批后台管理中是否屏蔽模板
                config.DisableResubmit = true;//审批详情页中是否禁用再次提交
                config.DisableStopProcessButton = true;//是否在审批后台管理中禁用停用操作
            }

            saveProcessRequest.ProcessConfig = config;
            saveProcessRequest.Name = ProcessName;
            if (!string.IsNullOrWhiteSpace(ProcessCode))
                saveProcessRequest.ProcessCode = ProcessCode;
            saveProcessRequest.Agentid = AgentId;
            saveProcessRequest.FakeMode = true;//不带流程的模板

            //表单
            saveProcessRequest.FormComponentList = formdata;
            request.SaveProcessRequest_ = saveProcessRequest;

            OapiProcessSaveResponse response = client.Execute(request, accessToken);
            return response;
        }

        /// <summary>
        /// 4.发起不带流程的审批实例 
        /// </summary>
        /// <param name="ProcessCode">审批模板Code</param>
        /// <param name="comvalues">表单参数列表</param>
        /// <param name="UserId">审批发起人</param>
        /// <param name="url">实例跳转URL</param>
        public OapiProcessWorkrecordCreateResponse WorkrecordCreate(string ProcessCode, List<FormComponentValueVoDomain> comvalues, string UserId, string url)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/process/workrecord/create");

            OapiProcessWorkrecordCreateRequest req = new OapiProcessWorkrecordCreateRequest();
            SaveFakeProcessInstanceRequestDomain obj1 = new SaveFakeProcessInstanceRequestDomain();
            obj1.Agentid = AgentId;
            obj1.ProcessCode = ProcessCode;
            obj1.OriginatorUserId = UserId; ;

            obj1.FormComponentValues = comvalues;//表单参数列表
            obj1.Url = url;
            req.Request_ = obj1;

            OapiProcessWorkrecordCreateResponse rsp = client.Execute(req, accessToken);
            return rsp;
        }

        /// <summary>
        /// 5.创建待办任务  (通过调用此接口，可以把待办事项的审批节点信息同步到钉钉待办。一个待办实例下最多创建100个待办事项。)
        /// </summary>
        /// <param name="ProcessInstanceId">审批实例ID</param>
        /// <param name="activityid">流程节点ID</param>
        /// <param name="tasks">任务列表</param>
        /// <returns></returns>
        public OapiProcessWorkrecordTaskCreateResponse Workrecord_Task_Create(string ProcessInstanceId, string activityid, List<TaskTopVoDomain> tasks)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/process/workrecord/task/create");
            OapiProcessWorkrecordTaskCreateRequest req = new OapiProcessWorkrecordTaskCreateRequest();
            SaveTaskRequestDomain obj1 = new SaveTaskRequestDomain();
            obj1.Agentid = AgentId;
            obj1.ProcessInstanceId = ProcessInstanceId;
            if (!string.IsNullOrWhiteSpace(activityid))
                obj1.ActivityId = activityid;//流程节点ID

            obj1.Tasks = tasks;
            req.Request_ = obj1;

            OapiProcessWorkrecordTaskCreateResponse response = client.Execute(req, accessToken);
            return response;
        }

        /// <summary>
        ///6. 查询用户待办事项   
        /// </summary>
        /// <param name="userId">用户id</param>
        /// <param name="offset">分页游标，从0开始，每次累加pagesize的值</param>
        /// <param name="pagesize">分页大小，最大50</param>
        /// <param name="status">0表示待处理，-1表示已经移除</param>
        public OapiProcessWorkrecordTaskQueryResponse Workrecord_Task_Query(string userId, long offset, long pagesize, long status)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/process/workrecord/task/query");
            OapiProcessWorkrecordTaskQueryRequest req = new OapiProcessWorkrecordTaskQueryRequest();
            req.Userid = userId;
            req.Offset = offset;
            req.Count = pagesize;
            req.Status = status;
            OapiProcessWorkrecordTaskQueryResponse rsp = client.Execute(req, accessToken);
            return rsp;
        }

        /// <summary>
        /// 7.更新待办任务状态  ；企业调用此接口，可以更新待办任务的状态
        /// </summary>
        /// <param name="ProcessInstanceId">实例ID</param>
        /// <param name="list3">任务列表</param>
        /// <returns></returns>
        public OapiProcessWorkrecordTaskUpdateResponse Workrecord_Task_Update(string ProcessInstanceId, List<OapiProcessWorkrecordTaskUpdateRequest.TaskTopVoDomain> list3)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/process/workrecord/task/update");
            OapiProcessWorkrecordTaskUpdateRequest req = new OapiProcessWorkrecordTaskUpdateRequest();
            OapiProcessWorkrecordTaskUpdateRequest.UpdateTaskRequestDomain obj1 = new OapiProcessWorkrecordTaskUpdateRequest.UpdateTaskRequestDomain();
            obj1.Agentid = AgentId;
            obj1.ProcessInstanceId = ProcessInstanceId;
            obj1.Tasks = list3;
            req.Request_ = obj1;
            OapiProcessWorkrecordTaskUpdateResponse rsp = client.Execute(req, accessToken);
            return rsp;
        }

        /// <summary>
        /// 8. 批量取消任务  ;企业调用此接口，可以实现在或签等场景下，批量将正在运行中的待办事项设置为CANCELED。
        /// </summary>
        /// <param name="ProcessInstanceId"></param>
        /// <param name="ActivityIds"></param>
        /// <returns></returns>
        public OapiProcessWorkrecordTaskgroupCancelResponse Workrecord_Task_Cancel(string ProcessInstanceId, List<string> ActivityIds)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/process/workrecord/taskgroup/cancel");
            OapiProcessWorkrecordTaskgroupCancelRequest req = new OapiProcessWorkrecordTaskgroupCancelRequest();
            UpdateTaskRequestDomain obj1 = new UpdateTaskRequestDomain();
            obj1.Agentid = AgentId;
            obj1.ProcessInstanceId = ProcessInstanceId;
            if (ActivityIds != null && ActivityIds.Count > 0)
                obj1.ActivityIdList = ActivityIds;
            req.Request_ = obj1;
            OapiProcessWorkrecordTaskgroupCancelResponse rsp = client.Execute(req, accessToken);
            return rsp;
        }

        /// <summary>
        /// 9.同步待办实例状态  当企业内部应用对应工作流的审批单结束时，可以调用此接口，更新对应审批实例的状态
        /// </summary>
        /// <param name="ProcessInstanceId">实例id。</param>
        /// <param name="status">实例状态，分为COMPLETED, TERMINATED</param>
        /// <param name="result">任务结果，分为agree和refuse</param>
        /// <returns></returns>
        public OapiProcessWorkrecordUpdateResponse WorkrecordUpdate(string ProcessInstanceId, string status, string result)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/process/workrecord/taskgroup/cancel");
            OapiProcessWorkrecordUpdateRequest req = new OapiProcessWorkrecordUpdateRequest();
            OapiProcessWorkrecordUpdateRequest.UpdateProcessInstanceRequestDomain obj1 = new OapiProcessWorkrecordUpdateRequest.UpdateProcessInstanceRequestDomain();
            obj1.Agentid = AgentId;
            obj1.ProcessInstanceId = ProcessInstanceId;
            obj1.Status = status;
            obj1.Result = result;
            req.Request_ = obj1;

            OapiProcessWorkrecordUpdateResponse rsp = client.Execute(req, accessToken);
            return rsp;
        }
    }
}
